package storage.v1;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.StringTokenizer;

import org.apache.commons.lang.StringEscapeUtils;

import com.onpositive.commons.platform.registry.IAdaptable2;
import com.onpositive.mediawiki.propertyparser.ParsedDocument;
import com.onpositive.wikitemplate.DefaultTemplateResolver;
import com.onpositive.wikitemplate.TemplateInfoProvider;

public class TableValueExtractor extends AbstractValueExtractor {

	@Override
	public void process(String documentContent, ParsedDocument pDoc, IParserProvider parserProvider, IAdaptable2 adaptable)
	{
		ITableInfoContainer container = adaptable.getAdapter( ITableInfoContainer.class ) ;
		if( container == null )
			return;
		
		List<String> tables = extractTables( documentContent ) ;
		
		for( String tableText : tables ){
			ArrayList<ArrayList<String>> tablValues = extractValues(tableText) ;
			if( tablValues == null )
				continue;
			
			if( tablValues.size() < 2 )
				continue ;
			
			preprocess( tablValues ) ;		
			
			ITableInfo ti = new BasicTableInfo( pDoc.getName(), tablValues ) ;
			container.addTableInfo(ti) ;
			
			for( int i = 0 ; i < tablValues.size() ; i++  )
			{
				final ArrayList<String> currentList = tablValues.get(i);
				final int size = currentList.size();
				
					for( String s : currentList ){					
					System.out.print( s )  ;
					System.out.print(" ")  ;
				}
				System.out.println()  ;				
			}
		}
		System.out.println()  ;
	}

	private TemplateInfoProvider TIProvider = new TemplateInfoProvider(){
		
		public boolean needToBeKilled( String str )
		{
			str = normalize(str) ;
			if( super.needToBeKilled(str) )
				return true ;
			
			return DefaultTemplateResolver.isDepricated(str) ;
		}
		
	};
	

	private void preprocess(ArrayList<ArrayList<String>> tablValues) {
		
		final int size1 = tablValues.size();
		for( int i = 0 ; i < size1 ; i++ )
		{
			final ArrayList<String> currentList = tablValues.get(i);
			final int size2 = currentList.size();
			for( int j = 0 ; j < size2 ; j++ )
			{
				String str = currentList.get(j) ;
				str = ParserV2.killComments(str) ;
				str = ParserV2.killRefs(str) ;
				str = DefaultTemplateResolver.resolveTemplates(str) ;
				str = ParserV2.killTemplates(str, TIProvider) ;
				
				str = str.replaceAll("&nbsp;", " ") ;
				str = str.replaceAll("&thinsp;", " ") ;
				str = StringEscapeUtils.unescapeHtml(str) ;
				char unbreakableSpace = 8201 ;
				str = str.replace(unbreakableSpace, ' ') ;
				
				currentList.set(j, str) ;				
			}			
		}
		
	}




	private ArrayList<ArrayList<String>> extractValues(String tableText)
	{
//		System.out.println(tableText) ;
		if( !(tableText.contains("|-")))
			return null ;
		
		ArrayList<ArrayList<String>> result = new ArrayList<ArrayList<String>>() ;
		
		ArrayList<String> currentRow = new ArrayList<String>() ;
		StringTokenizer tokenizer = new StringTokenizer(tableText, "\n");

		while( tokenizer.hasMoreTokens() )
		{
			String str = tokenizer.nextToken().trim() ;
			int start = Math.max( str.indexOf("!"),str.indexOf("|") ) ;
			if( start < 0 )
				continue ;
			
			//str = str.substring(start) ;
			
			if( str.startsWith("|-") ||  str.startsWith("|+") ){
				if( currentRow.size() > 0 ){
					result.add( currentRow ) ;
					currentRow = new ArrayList<String>() ;
				}				
			}
			else if ( str.startsWith("|") || str.startsWith("!") ){
				
				str = str.substring(1);
				ArrayList<String> lst = splitRow(str);
				
				String s0 = lst.get(0) ;
				int ind = detectStart(s0) ;
				if( ind >= 0 )
					lst.set(0, s0.substring(ind) ) ;
					
				for( String s : lst )
					currentRow.add( s.trim() ) ;
			}		
		}
		
		if( currentRow.size() > 0 ){
			result.add( currentRow ) ;
			currentRow = new ArrayList<String>() ;
		}
			
		return result ;
	}

	private ArrayList<String> splitRow(String str) {
		
		ArrayList<String> result = new ArrayList<String>() ;
		int prev = 0 ;
		int templateDepth = 0 ;
		final int l = str.length();
		for( int i = 0 ; i < l ; i++ )
		{
			if( str.startsWith("{{",i) )
			{
				i++ ;
				templateDepth++ ;
				continue ;
			}
			if( str.startsWith("}}",i) )
			{
				i++ ;
				templateDepth-- ;
				continue ;
			}
			if( templateDepth > 0 )
				continue ;
			if( str.startsWith("||",i) || str.startsWith("!!",i) )
			{
				result.add( str.substring(prev, i)) ;
				prev = i+2 ;
				i++ ;
			}
		}
		result.add( str.substring(prev, l)) ;
		return result;
	}



	private int detectStart(String str ) {
		
		final int l = str.length();
		int templateDepth = 0 ;
		for( int i = 0 ; i < l ; i++ )
		{
			if( str.startsWith("[[",i) )
			{
				i = str.indexOf("]]", i) ;
				i++ ;
				continue ;
			}
			if( str.startsWith("}}",i) )
			{
				i++ ;
				templateDepth-- ;
				continue ;
			}
			if( str.startsWith("{{",i) )
			{
				i++ ;
				templateDepth++ ;
				continue ;
			}
			if( str.startsWith("}}",i) )
			{
				i++ ;
				templateDepth-- ;
				continue ;
			}
			if( templateDepth > 0 )
				continue ;
			
			if( str.charAt(i) == '|' )
				return i+1 ;
		}
		return 0;
	}

	private List<String> extractTables(String text) {
		
		//text = ParserV2.killComments(text) ;
		ArrayList<String> result = new ArrayList<String>() ;		
		int prev = 0 ;
		for( int ind = text.indexOf("{|") ; ind >= 0 ; ind = text.indexOf("{|",prev) )
		{
			ind += 2 ;
			prev = detectClosingBracket( text, ind ) ;
			result.add( text.substring(ind, prev) ) ;
		}		
		return result;
	}

	private int detectClosingBracket(String text, int i) {
		
		int count=1;
		final int l = text.length()-1;
		int templateDepth = 0 ;
		for( ; i < l && count > 0 ; i++ )
		{
			if( text.startsWith("{{",i) )
			{
				i++ ;
				templateDepth++ ;
				continue ;
			}
			if( text.startsWith("}}",i) )
			{
				i++ ;
				templateDepth-- ;
				continue ;
			}
			if( templateDepth > 0 )
				continue ;
			
			if( text.startsWith("|}", i) )
			{
				count-- ;
				if( count == 0 )
					break ;
				continue ;
			}
			if( text.startsWith("{|", i) )
			{
				count++ ;
				continue ;
			}			
		}		
		System.out.println( text.substring(i) ) ;		
		return i;
	}
	
	@Override
	public void dispose() {}

}

